package com.fingard.dsp.bank.directbank.abc02;

import java.io.File;
import java.rmi.UnexpectedException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fingard.client.DspClient;
import com.fingard.dsp.bank.directbank.bankInterface.IElecBillQuery;
import com.fingard.dsp.bank.helpers.FileType;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.*;
import com.fingard.dsp.bank.reqrespobj.elecbillquery.detail.*;
import com.fingard.io.FileHelper;
import com.fingard.net.TcpReceiver;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * Created by dalt on 2017/11/22.
 */
public class ABC02ElecBill extends ABC02ElecBase implements IElecBillQuery {


    @Override
    public RetAtsB001OperBillQry D_OperBill_Query_Req(ReqB001OperBillQry query) throws Exception {
        RetAtsB001OperBillQry result = new RetAtsB001OperBillQry(query.reqHeader);
        result.writeStart();
        while (query.readRecord()) {
            ReqB001OperBillQryDetail detail = query.detail;
            switch (Integer.parseInt(detail.queryType)) {
                //查询类型 1-待操作 2-待应答 3-待撤回
                case 1:
                    queryUnhandled(detail, result);
                    break;
                case 2:
                    queryWaitingForResponse(detail, result);
                    break;
                case 3:
                    queryWaitingForRevoke(detail, result);
                    break;
            }
        }

        result.writeAfter();
        return result;
    }

    @Override
    public RetAtsB002BillTransQry D_B002_BillTrans_Query(ReqB002BillTransQry query) throws Exception {
        RetAtsB002BillTransQry result = new RetAtsB002BillTransQry(reqHeader);
        result.writeRespCode("-1");
        result.writeRespInfo("农行不支持该操作");
        return result;
    }

//    public static void D_B004_BillFront_Query_test() throws Exception {
//        //处理错误，票据号无
//        ABC02ElecBill trans = prepare();
//
//        XmlTextReader reader = new XmlTextReader(
//                "<ATSYH version=\"5.1.0.0\">\n" +
//                        "\t<TransReq>\n" +
//                        "\t\t<BankCode>ABC</BankCode>\n" +
//                        "\t\t<!--直联线路代码,参见数据字典.必填-->\n" +
//                        "\t\t<TransType>B004</TransType>\n" +
//                        "\t\t<!--指令类型,参见数据字典.必填-->\n" +
//                        "\t\t<TransSeqID>01291213</TransSeqID>\n" +
//                        "\t\t<!--请求唯一流水号,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransTime>%s</TransTime>\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")) +
//                        "\t\t<!--请求日期时间,参见数据字典.必填-->\n" +
//                        "\t\t<TransParam>\n" +
//                        "\t\t\t<DetailRecord>\n" +
//                        "\t\t\t\t<ActNum>402001040005870</ActNum>\n" +
//                        "\t\t\t\t<!--银行账号.必填-->\n" +
//                        "\t\t\t\t<BusiType>5</BusiType>\n" +
//                        "\t\t\t\t<!--业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-出票保证 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿-->\n" +
//                        "\t\t\t\t<QueryType>2</QueryType>\n" +
//                        "\t\t\t\t<!--查询类型 1-待操作 2-待应答 3-待撤回-->\n" +
//                        "\t\t\t\t<BillNo>1212131212131</BillNo>\n" +
//                        "\t\t\t\t<!--电子票据序列号-->\n" +
//                        "\t\t\t\t<BusiNo>34534523</BusiNo>\n" +
//                        "\t\t\t\t<!--业务流水号-->\n" +
//                        "\t\t\t</DetailRecord>\n" +
//                        "\t\t</TransParam>\n" +
//                        "\t</TransReq>\n" +
//                        "</ATSYH>"
//        );
//
//        ReqRespHeader header = new ReqRespHeader();
//        header.reqSeqID = getSeqID();
//        header.transSeqID = getSeqID();
//        header.bankCode = "ABC";
//        trans.reqHeader = header;
//        ReqB004BillFrontQry submit = new ReqB004BillFrontQry(reader, header);
//
//        RetAtsB004BillFrontQry ret = trans.D_B004_BillFront_Query(submit);
//
//
//        System.out.println(trans.getSbLog());
//    }

    @Override
    public RetAtsB004BillFrontQry D_B004_BillFront_Query(ReqB004BillFrontQry query) throws Exception {

        RetAtsB004BillFrontQry resp = new RetAtsB004BillFrontQry(reqHeader);
        resp.writeStart();
        while (query.readRecord()) {
            ReqB004BillFrontQryDetail detail = query.detail;

            ABC02Header header = new ABC02Header();
            XmlTextWriter writer = new XmlTextWriter();
            header.CCTransCode = "CQRT14";
            header.msgType = "1017";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = reqHeader.transSeqID;
            writeEleCommonHead(writer, header);

            //<IdNb>票据号码</IdNb>
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>账号</DbAccNo>
            //<DbProv>省市代码</DbProv>
            //<DbCur>货币码</DbCur>
            //</Cmp>
            writer.writeStartElement("Cmp");
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeEndElement();

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            String tmpRespCode;
            String tmpRespInfo = "";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                        tmpRespCode = "0";
                        resp.respCode = "0";
                        resp.respInfo = tmpRetInfo;
                        resp.billState = tmpBkReader.getFirstText("/ap/Hermes/EBInfo/BillSta");//Hermes/EBInfo/BillSta	票据状态
                        resp.billNo = tmpBkReader.getFirstText("/ap/Hermes/EBInfo/IdNb");//Hermes/EBInfo/IdNb	票据号码
                        resp.billAmt = tmpBkReader.getFirstText("/ap/Hermes/EBInfo/BillAmt");//Hermes/EBInfo/BillAmt	票据金额
                        resp.billType = ELE_BILL_TYPE.reverse().getOrDefault(tmpBkReader.getFirstText("/ap/Hermes/EBInfo/BillTyp"), tmpBkReader.getFirstText("/ap/Hermes/EBInfo/BillTypNam"));//Hermes/EBInfo/BillTyp	票据类型
                        resp.transFlag = ELE_TRANS_FLAG.reverse().getOrDefault(tmpBkReader.getFirstText("/ap/Hermes/EBInfo/TransFlg"), tmpBkReader.getFirstText("/ap/Hermes/EBInfo/TransFlgNam"));//Hermes/EBInfo/TransFlg	不可转让标识
                        resp.issDate = tmpBkReader.getFirstText("/ap/Hermes/EBInfo/IssDat");//Hermes/EBInfo/IssDat	出票日期
                        resp.dueDate = tmpBkReader.getFirstText("/ap/Hermes/EBInfo/DueDat");//Hermes/EBInfo/DueDat	到期期日
                        resp.mustPay = ELE_DUEPAYTYPE.reverse().getOrDefault(tmpBkReader.getFirstText("/ap/Hermes/BillInfo/DuePayTyp"), tmpBkReader.getFirstText("/ap/Hermes/BillInfo/DuePayTypNam"));//Hermes/BillInfo/DuePayTyp	到期无条件支付承诺
                        //resp. = tmpBkReader.getFirstText("/ap/Hermes/BillInfo/ContNo");//Hermes/BillInfo/ContNo	交易合同编号
                        //resp. = tmpBkReader.getFirstText("/ap/Hermes/BillInfo/InvoiceNo");//Hermes/BillInfo/InvoiceNo	发票号码
                        resp.accpAct = tmpBkReader.getFirstText("/ap/Hermes/AccepteInfor/AcepAccNo");//Hermes/AccepteInfor/AcepAccNo	账号
                        resp.accpName = tmpBkReader.getFirstText("/ap/Hermes/AccepteInfor/AcepNam");//Hermes/AccepteInfor/AcepNam	名称
                        resp.accpBnkCode = tmpBkReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnk");//Hermes/AccepteInfor/AcepOpBnk	开户行行号
                        resp.accpBnkName = tmpBkReader.getFirstText("/ap/Hermes/AccepteInfor/AcepOpBnkNam");//Hermes/AccepteInfor/AcepOpBnkNam	开户行名称
                        resp.drawName = tmpBkReader.getFirstText("/ap/Hermes/DrawerInfo/FrNam");//Hermes/DrawerInfo/FrNam 	名称
                        resp.drawAct = tmpBkReader.getFirstText("/ap/Hermes/DrawerInfo/FrAccNo");//Hermes/DrawerInfo/FrAccNo    	账号
                        resp.drawBnkCode = tmpBkReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnk");//Hermes/DrawerInfo/FrOpBnk    	开户行行号
                        resp.drawBnkName = tmpBkReader.getFirstText("/ap/Hermes/DrawerInfo/FrOpBnkNam");//Hermes/DrawerInfo/FrOpBnkNam 	开户行名称
                        resp.payeeAct = tmpBkReader.getFirstText("/ap/Hermes/PayeeInfo/ToAccNo");//Hermes/PayeeInfo/ToAccNo    	账号
                        resp.payeeName = tmpBkReader.getFirstText("/ap/Hermes/PayeeInfo/ToNam");//Hermes/PayeeInfo/ToNam      	名称
                        resp.payeeBnkCode = tmpBkReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnk");//Hermes/PayeeInfo/ToOpBnk    	开户行行号
                        resp.payeeBnkName = tmpBkReader.getFirstText("/ap/Hermes/PayeeInfo/ToOpBnkNam");//Hermes/PayeeInfo/ToOpBnkNam 	开户行名称

                    } else {
                        tmpRespCode = "-1";
                        if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {
                            tmpRespInfo = tmpRetInfo;
                        } else {
                            tmpRespInfo = tmpRetRxtInfo;
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpStrRet[1];
            }


            resp.writeRespCode(tmpRespCode);
            resp.writeRespInfo(tmpRespInfo);
            resp.writeRetDetail();
        }

        resp.writeEnd();
        return resp;
    }

//    public static void D_B005_BillBack_Query_test() throws Exception {
//        //无数据
//        ABC02ElecBill trans = prepare();
//
//        XmlTextReader reader = new XmlTextReader(
//                "<ATSYH version=\"5.1.0.0\">\n" +
//                        "\t<TransReq>\n" +
//                        "\t\t<BankCode>ABC</BankCode>\n" +
//                        "\t\t<!--直联线路代码,参见数据字典.必填-->\n" +
//                        "\t\t<TransType>B005</TransType>\n" +
//                        "\t\t<!--指令类型,参见数据字典.必填-->\n" +
//                        "\t\t<TransSeqID>25545242432</TransSeqID>\n" +
//                        "\t\t<!--请求唯一流水号,参见数据字典.必填-->\n" +
//                        String.format("\t\t<TransTime>%s</TransTime>\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")) +
//                        "\t\t<!--请求日期时间,参见数据字典.必填-->\n" +
//                        "\t\t<TransParam>\n" +
//                        "\t\t\t<DetailRecord>\n" +
//                        "\t\t\t\t<ActNum>402001040005870</ActNum>\n" +
//                        "\t\t\t\t<!--银行账号.必填-->\n" +
//                        "\t\t\t\t<BillNo>2352342342324</BillNo>\n" +
//                        "\t\t\t\t<!--电子票据序列号-->\n" +
//                        "        <BusiType></BusiType>\n" +
//                        "        <!--业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-出票保证 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿-->\n" +
//                        "        <QueryType></QueryType>\n" +
//                        "        <!--查询类型 1-待操作 2-待应答 3-待撤回-->\n" +
//                        "        <BusiNo></BusiNo>\n" +
//                        "        <!--业务流水号-->\n" +
//                        "\t\t\t</DetailRecord>\n" +
//                        "\t\t</TransParam>\n" +
//                        "\t</TransReq>\n" +
//                        "</ATSYH>"
//        );
//
//        ReqRespHeader header = new ReqRespHeader();
//        header.reqSeqID = getSeqID();
//        header.transSeqID = getSeqID();
//        header.bankCode = "ABC";
//        trans.reqHeader = header;
//        ReqB005BillBackQry submit = new ReqB005BillBackQry(reader, header);
//
//        RetAtsB005BillBackQry ret = trans.D_B005_BillBack_Query(submit);
//
//
//        System.out.println(trans.getSbLog());
//    }

    @Override
    public RetAtsB005BillBackQry D_B005_BillBack_Query(ReqB005BillBackQry query) throws Exception {
//        RetAtsB005BillBackQry result = new RetAtsB005BillBackQry(reqHeader);
//        result.writeRespCode("-1");
//        result.writeRespInfo("农行无对应接口");
//        return result;
        RetAtsB005BillBackQry resp = new RetAtsB005BillBackQry(reqHeader);
        resp.writeStart();
        while (query.readRecord()) {
            ReqB005BillBackQryDetail detail = query.detail;

            ABC02Header header = new ABC02Header();
            XmlTextWriter writer = new XmlTextWriter();
            header.CCTransCode = "CQRM06";
            header.msgType = "1019";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = reqHeader.transSeqID;
            writeEleCommonHead(writer, header);


            //<IdNb>票据号码</IdNb>
            writer.writeElementString("IdNb", detail.billNo);
            writer.writeEndElement();

            //<Cmp>
            //<DbAccNo>账号</DbAccNo>
            //<DbProv>省市代码</DbProv>
            //<DbCur>货币码</DbCur>
            //</Cmp>
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeEndElement();

            //发送银行
            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            String tmpRespCode = "";
            String tmpRespInfo = "";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                        int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                        int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                        if (tmpRecordNum > 0) {
                            try {
                                String tmpDataMFS = "";
                                String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                    String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                    String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                                    this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                    if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                        DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                        dspClient.charsetName = getCharset();
                                        TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                        if (tcpRec.isCompleted) {
                                            if (tcpRec.isRtnBinaryFile) {
                                                tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            } else {
                                                String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                        }
                                    } else {
                                        tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                    }
                                    if (tmpDataMFS == null) {
                                        this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                                    } else {
                                        this.WriteBankLogStep3(tmpDataMFS);
                                    }
                                } else {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                                    if (tmpDataMFS == null) {
                                        tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                                    }
                                }
                                if (tmpDataMFS != null) {
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                                    if (tmpSbLog.length() == 0) {
                                        tmpRespCode = "0";
                                        /*
                                    0业务种类|1业务种类名称|2签收日期|3签收人类别|4签收人类别名称|
                                    5签收人名称|6签收人组织机构代码|7签收人开户行号|8签收人承接行行名|9签收人账号|
                                    10利率|11备注|
										 * */
                                        for (int i = 0; i < tmpArrayList.size(); i++) {
                                            RetAtsB005BillBackQryDetail respDetail = new RetAtsB005BillBackQryDetail();
                                            String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);
                                            if ("001".equals(tmpEachArr[0])) {
                                                continue;
                                            }
                                            respDetail.transCode = ELE_BUS_TYPE.getOrDefault(tmpEachArr[0], tmpEachArr[1]);
                                            respDetail.respDate = tmpEachArr[2];
                                            respDetail.receName = tmpEachArr[5];
                                            respDetail.billNo = detail.billNo;
                                            if (i == 0) {
                                                respDetail.applyName = "";
                                                respDetail.applyDate = "";
                                            } else {
                                                respDetail.applyName = tmpArrayList.get(i - 1).get(5);
                                            }
                                            respDetail.receName = tmpEachArr[5];
                                            respDetail.respDate = tmpEachArr[2];
                                            respDetail.respFlag = "1";
                                            respDetail.respCode = "0";
                                            resp.writeDetail(respDetail);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpSbLog.toString();
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "数据为空";
                                }
                            } catch (UnexpectedException ex) {
                                WriteBankLogLn("解析MFS文件失败, 尝试直接解析报文数据...");
                                while(tmpBkReader.read("/ap/EBList/EBInfo")){
                                    RetAtsB005BillBackQryDetail respDetail = new RetAtsB005BillBackQryDetail();
                                    if ("001".equals(tmpBkReader.readedXElement.getSingleText("BusTyp"))) {
                                        continue;
                                    }
                                    respDetail.transCode = ELE_BUS_TYPE.getOrDefault(tmpBkReader.readedXElement.getSingleText("BusTyp"), tmpBkReader.readedXElement.getSingleText("BusTypNam"));
                                    respDetail.respDate = tmpBkReader.readedXElement.getSingleText("RecvDate");
                                    respDetail.receName = tmpBkReader.readedXElement.getSingleText("RecvTyp");
                                    respDetail.billNo = detail.billNo;
                                    respDetail.applyName = "";
                                    respDetail.applyDate = "";
                                    respDetail.receName = tmpBkReader.readedXElement.getSingleText("RecvNam");
                                    respDetail.respDate = tmpBkReader.readedXElement.getSingleText("RecvDate");
                                    respDetail.respFlag = "1";
                                    respDetail.respCode = "0";
                                    resp.writeDetail(respDetail);
                                }
                            }
                        }
                    } else {
                        tmpRespCode = "-1";
                        if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {

                            tmpRespInfo = tmpRetInfo;
                        } else {
                            tmpRespInfo = tmpRetRxtInfo;
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpStrRet[1];
            }


            resp.writeRespCode(tmpRespCode);
            resp.writeRespInfo(tmpRespInfo);
        }

        resp.writeEnd();
        return resp;
    }

    @Override
    public RetAtsB006BillStateQry D_B006_BillState_Qeury(ReqB006BillStateQry query) throws Exception {
        RetAtsB006BillStateQry resp = new RetAtsB006BillStateQry(reqHeader);
        resp.writeStart();
        while (query.readRecord()) {
            ReqB006BillStateQryDetail detail = query.detail;

            //出票特殊处理
            if (StringHelper.equals(detail.operType, "1") && StringHelper.equals(detail.busiType, "1")) {
                ABC02Header header = new ABC02Header();
                XmlTextWriter writer = new XmlTextWriter();
                header.CCTransCode = "CQRM42";
                header.msgType = "0018";
                header.ReqDateTime = new Date();
                header.ReqSeqNo = reqHeader.transSeqID;
                writeEleCommonHead(writer, header);

                //<IdNb>票据号码</IdNb>
                //<BillTyp>票据种类</BillTyp>
                //<BillAmtFr>票据起始金额</BillAmtFr>
                //<BilAmtTo>票据终止金额</BilAmtTo>
                //<IssDatFr>出票起始日期</IssDatFr>
                //<IssDatTo>出票终止日期</IssDatTo>
                //<BillSta>票据状态</BillSta >
                //<BatchNo>批次号</BatchNo>
                writer.writeElementString("IdNb", "", true);
                writer.writeElementString("BillTyp", ELE_BILL_TYPE.getNotNull(detail.billType));
                writer.writeElementString("BillAmtFr", "", true);
                writer.writeElementString("BilAmtTo", "", true);
                writer.writeElementString("IssDatFr", "", true);
                writer.writeElementString("IssDatTo", "", true);
                writer.writeElementString("BillSta", "", true);
                writer.writeElementString("BatchNo",
                        detail.reqSeqID.length() > 10 ? query.detail.reqSeqID.substring(query.detail.reqSeqID.length() - 10)
                                : query.detail.reqSeqID);
                writer.writeEndElement();

                //<Cmp>
                //<DbAccNo>账号</DbAccNo>
                //<DbProv>省市代码</DbProv>
                //<DbCur>货币码</DbCur>
                //</Cmp>
                writer.writeStartElement("Cmp");
//                writer.writeElementString("DbAccNo", detail.actNum);
//                writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                String dbCur = convertCurToBank(detail.billCur);
                writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                writer.writeEndElement();

                //发送银行
                writer.writeEndDocument();
                String[] tmpStrRet = sendToBank(writer.toXmlString());
                String tmpRespCode = "";
                String tmpRespInfo = "";
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                            int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                            if (tmpRecordNum > 0) {
                                String tmpDataMFS = "";
                                String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                                if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                                    String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                    String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                                    this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                    if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                        WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                        DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                        dspClient.charsetName = getCharset();
                                        TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                        if (tcpRec.isCompleted) {
                                            if (tcpRec.isRtnBinaryFile) {
                                                tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            } else {
                                                String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                                WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                            }
                                        } else {
                                            this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                        }
                                    } else {
                                        tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                    }
                                    if (tmpDataMFS == null) {
                                        this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                                    } else {
                                        this.WriteBankLogStep3(tmpDataMFS);
                                    }
                                } else {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                                    if (tmpDataMFS == null) {
                                        tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                                    }
                                }
                                if (tmpDataMFS != null) {
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                                    if (tmpSbLog.length() == 0) {
                                        tmpRespCode = "0";
                                        for (int i = 0; i < tmpArrayList.size(); i++) {
                                     /*
                                    0票据号码|1票据金额|2收票人账号|3收票人名称|4票据状态|
                                    5批次号|6报文类型|7处理时间|8处理结果|9清分失败原因|
										 * */
                                            RetAtsB006BillStateQryDetail respDetail = new RetAtsB006BillStateQryDetail();
                                            String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);

                                            respDetail.respCode = "0";
                                            respDetail.billNo = tmpEachArr[0];
                                            respDetail.billState = tmpEachArr[4];
                                            respDetail.reqSeqID = tmpEachArr[5];
                                            respDetail.busiNo = tmpEachArr[5];
                                            respDetail.respInfo = tmpEachArr[8] + tmpEachArr[9];

                                            //如果票据状态为待承兑或者其他，则表示出票成功
                                            if (StringHelper.isNullOrEmpty(respDetail.payInfoCode) &&
                                                    StringHelper.isNullOrEmpty(respDetail.transState) &&
                                                    !StringHelper.isNullOrEmpty(respDetail.billState)) {
                                                respDetail.payInfoCode = respDetail.transState = "SU00";
                                            }

                                            resp.writeDetail(respDetail);
                                        }
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = tmpSbLog.toString();
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "数据为空";

                                }
                            }
                        } else {
                            tmpRespCode = "-1";
                            if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {
                                tmpRespInfo = tmpRetInfo;
                            } else {
                                tmpRespInfo = tmpRetRxtInfo;
                            }
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                }


                resp.writeRespCode(tmpRespCode);
                resp.writeRespInfo(tmpRespInfo);
            } else {
                //兴业银行票据票据池的票据交易结果查询，直接复用电票已经实现的CMLR34接口，如果一个接口改动，电票和票据池都要改动
                ABC02Header header = new ABC02Header();
                XmlTextWriter writer = new XmlTextWriter();
                header.CCTransCode = "CMLR34";
                header.msgType = "1035";
                header.ReqDateTime = new Date();
                header.ReqSeqNo = reqHeader.transSeqID;
                writeEleCommonHead(writer, header);


                //<BusCode>业务编号</BusCode>
                writer.writeElementString("BusCode", detail.reqSeqID);
                //<IdNb>票据号码</IdNb>
                writer.writeElementString("IdNb", detail.billNo);
                //<Typ>申请回复类型</Typ>
                //<!--操作类型 1-申请 2-签收 3-驳回 4-撤销-->
                if ("1".equals(detail.operType) || "4".equals(detail.operType)) {
                    writer.writeElementString("Typ", "ST00");
                } else if ("2".equals(detail.operType) || "3".equals(detail.operType)) {
                    writer.writeElementString("Typ", "ST01");
                }
                //<TransCode>交易代码</TransCode>
                if ("4".equals(detail.operType)) {
                    //撤票和撤销分离
                    if ("1".equals(detail.busiType)) {
                        writer.writeElementString("TransCode", "TRE005");
                    } else {
                        writer.writeElementString("TransCode", "TRE019");
                    }
                } else {
                    writer.writeElementString("TransCode", ELE_TRANSCODE.getNotNull(detail.busiType));
                }
                writer.writeEndElement();

                //<Cmp>
                //<DbAccNo>查询人帐号</DbAccNo>
                //<DbProv>查询人省市代码</DbProv>
                //<DbCur>货币码</DbCur>
                //</Cmp>
                writer.writeStartElement("Cmp");
//                writer.writeElementString("DbAccNo", detail.actNum);
//                writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//                writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
                writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
                writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
                String dbCur = convertCurToBank(detail.billCur);
                writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
                writer.writeEndElement();


                //发送银行
                writer.writeEndDocument();
                String[] tmpStrRet = sendToBank(writer.toXmlString());
                String tmpRespCode = "";
                String tmpRespInfo = "";
                RetAtsB006BillStateQryDetail respDetail = new RetAtsB006BillStateQryDetail();
                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                        String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                        if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                            String result = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");
//                            if(StringHelper.hasAnyChar(result)&&"SA01".equals(result.trim())){
//                                double differSecs  = DateHelper.getDifferSecs(new Date(), Format.DateTime21Format.parse(detail.operateDate));
//                                if(differSecs<180){
//                                    tmpRespCode = "-1";
//                                    tmpRespInfo = "请在发起交易3分钟之后再查询交易结果+:" +result;
//                                }
//                            }
                            tmpRespCode = "0";
                            tmpRespInfo = tmpRetInfo;

                            respDetail.billState = tmpBkReader.getFirstText("/ap/Hermes/BillSta");//Hermes/BillSta	票据状态
                            respDetail.billNo = detail.billNo;
                            respDetail.busiNo = detail.reqSeqID;
                            respDetail.respCode = "0";
                            respDetail.respInfo = tmpBkReader.getFirstText("/ap/Hermes/DealResult");//Hermes/DealResult	处理结果
                            if ("2".equals(query.detail.operType) || "3".equals(query.detail.operType)) {
                                respDetail.payInfoCode = "2+" + tmpBkReader.getFirstText("/ap/Hermes/ResTyp");//Hermes/ResTyp	签收标记
                                respDetail.transState = "2+" + tmpBkReader.getFirstText("/ap/Hermes/ResTyp");//Hermes/ResTyp	签收标记
                            } else if ("4".equals(query.detail.operType)) {
                                String resTyp = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");
//                                if("SA01".equals(resTyp)) {
//                                    respDetail.payInfoCode = "TRE019+" +resTyp ;//Hermes/ResTyp	签收标记
//                                    respDetail.transState = "TRE019+" + resTyp;
//                                }else{
                                respDetail.payInfoCode = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");//Hermes/ResTyp	签收标记
                                respDetail.transState = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");//Hermes/ResTyp	签收标记
//                                }
                            } else {
                                respDetail.payInfoCode = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");//Hermes/ResTyp	签收标记
                                respDetail.transState = tmpBkReader.getFirstText("/ap/Hermes/ResTyp");
                            }
                        } else {
                            tmpRespCode = "-1";
                            if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {
                                tmpRespInfo = tmpRetInfo;
                            } else {
                                tmpRespInfo = tmpRetRxtInfo;
                            }
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSbMsg.toString();
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpStrRet[1];
                }
                if ("-1".equals(tmpRespCode)) {
                    respDetail = new RetAtsB006BillStateQryDetail();
                    respDetail.respCode = "-1";
                    respDetail.respInfo = tmpRespInfo;
                }
                resp.writeDetail(respDetail);
            }

        }

        resp.writeEnd();
        return resp;
    }

    @Override
    public RetAtsB007BillKzsrQry D_B007_BillKzsr_Query(ReqB007BillKzsrQry query) throws Exception {
        RetAtsB007BillKzsrQry resp = new RetAtsB007BillKzsrQry(reqHeader);
        resp.writeStart();
        while (query.readRecord()) {
            ABC02Header header = new ABC02Header();
            XmlTextWriter writer = new XmlTextWriter();
            ReqB007BillKzsrQryDetail detail = query.detail;

            header.CCTransCode = "CQRM10";
            header.msgType = "0222";
            header.ReqDateTime = new Date();
            header.ReqSeqNo = reqHeader.transSeqID;
            writeEleCommonHead(writer, header);
            //<EBInfo>
            //<IdNb>票据号码</IdNb>
            //</EBInfo>
            writer.writeElementString("IdNb", detail.billNo);
            //<Cmp>
            //<DbAccNo>账号</DbAccNo>
            //<DbProv>省市代码</DbProv>
            //<DbCur>货币码</DbCur>
            //</Cmp>
            writer.writeEndElement();
            writer.writeStartElement("Cmp");
//            writer.writeElementString("DbAccNo", detail.actNum);
//            writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//            writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
            writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
            writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
            String dbCur = convertCurToBank(detail.billCur);
            writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
            writer.writeEndElement();


            //发送银行

            writer.writeEndDocument();
            String[] tmpStrRet = sendToBank(writer.toXmlString());
            String tmpRespCode = "";
            String tmpRespInfo = "";
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                    String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                    String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                    if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                        int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                        int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                        if (tmpRecordNum > 0) {
                            String tmpDataMFS = "";
                            String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                            if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
//                                String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                                String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                                this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                                if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                    WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                    DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                    dspClient.charsetName = getCharset();
                                    TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                    if (tcpRec.isCompleted) {
                                        if (tcpRec.isRtnBinaryFile) {
                                            tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                        } else {
                                            String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                            WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                        }
                                    } else {
                                        this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                    }
                                } else {
                                    tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                                }
                                if (tmpDataMFS == null) {
                                    this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                                } else {
                                    this.WriteBankLogStep3(tmpDataMFS);
                                }
                            } else {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                                if (tmpDataMFS == null) {
                                    tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                                }
                            }
                            if (tmpDataMFS != null) {
                                StringBuilder tmpSbLog = new StringBuilder();
                                List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                                if (tmpSbLog.length() == 0) {
                                    tmpRespCode = "0";
                                    for (int i = 0; i < tmpArrayList.size(); i++) {
                                     /*
                                        0被追索人账号|1被追索人名称|2被追索人ID|
										 * */
                                        RetAtsB007BillKzsrQryDetail respDetail = new RetAtsB007BillKzsrQryDetail();
                                        String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);

                                        populateCQRT22(respDetail, detail.actNum, detail.actArea, detail.billCur, tmpEachArr[2]);

                                        resp.writeDetail(respDetail);
                                    }
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = tmpSbLog.toString();
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = "数据为空";
                            }
                        }
                    } else {
                        tmpRespCode = "-1";
                        if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {

                            tmpRespInfo = tmpRetInfo;
                        } else {
                            tmpRespInfo = tmpRetRxtInfo;
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpStrRet[1];
            }

            resp.writeRespCode(tmpRespCode);
            resp.writeRespInfo(tmpRespInfo);
        }

        resp.writeEnd();
        return resp;
    }

    @Override
    public RetAtsB008HistoricalBillQry D_B008_HistoricalBillQuery(ReqB008HistoricalBillQry query) throws Exception {
        RetAtsB008HistoricalBillQry result = new RetAtsB008HistoricalBillQry(reqHeader);
        result.respCode = "-1";
        result.respInfo = "DSP未实现接口";
        result.writeBefore();
        result.writeAfter();
        return result;
    }

    @Override
    public RetAtsB009DrawBillQry D_B009_DrawBillQuery(ReqB009DrawBillQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB010ProtocolStateQry D_B010_ProtocolStateQuery(ReqB010ProtocolStateQry query) throws Exception {
        return null;
    }

    @Override
    public RetAtsB011TransFlagQry D_B011_TransFlagQuery(ReqB011TransFlagQry query) throws Exception {
        return null;
    }

    public void queryUnhandled(ReqB001OperBillQryDetail detail, RetAtsB001OperBillQry Resp) throws
            Exception {
        ABC02Header header = new ABC02Header();
        XmlTextWriter writer = new XmlTextWriter();


        Map<String, String> msgTypeMap = new HashMap<String, String>();
        //业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-出票保证 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿
        msgTypeMap.put("1", "0041");
        msgTypeMap.put("3", "0031");
        msgTypeMap.put("4", "0101");
        msgTypeMap.put("5", "0181");
        msgTypeMap.put("6", "0191");
        msgTypeMap.put("7", "0171");
        msgTypeMap.put("8", "0171");
        msgTypeMap.put("10", "0111");
        msgTypeMap.put("12", "0201");
        msgTypeMap.put("13", "0221");
        msgTypeMap.put("14", "0231");
        if (!msgTypeMap.containsKey(detail.busiType)) {
            Resp.writeRespCode("-1");
            Resp.writeRespInfo("不支持的待申请类业务类型【" + detail.busiType + "】");
            return;
        }

        header.CCTransCode = "CQRM02";
        header.msgType = msgTypeMap.get(detail.busiType);
        header.ReqDateTime = new Date();
        header.ReqSeqNo = reqHeader.transSeqID;
        writeEleCommonHead(writer, header);

        //<EBQryInfo>
        //<BillTyp>票据种类</BillTyp>
        //<IdNb>票据号码</IdNb>
        //<IssDatFr>出票起始日期</IssDatFr>
        //<IssDatTo>出票终止日期</IssDatTo>
        //<DueDatFr>到期起始日期</DueDatFr>
        //<DueDatTo>到期终止日期</DueDatTo>
        //<IssAmtFr>票据起始金额</IssAmtFr>
        //<IssAmtTo>票据终止金额</IssAmtTo>
        //<FrNam>出票人名称</FrNam>
        //<AcepNam>承兑人名称</AcepNam>
        //<ToNam>收票人名称</ToNam>
        //<CpsrProv>出质人省市代码</CpsrProv>
        //<CpsrAccNo>出质人账号</CpsrAccNo>
        //<CztnDatFr>质压申请起始日期</CztnDatFr>
        //<CztnDatTo>质压申请终止日期</CztnDatTo>
        //</EBQryInfo>
        writer.writeStartElement("EBQryInfo");
        writer.writeElementString("BillTyp", ELE_BILL_TYPE.get(detail.billType));
        writer.writeElementString("IdNb", detail.billNo);
        writer.writeElementString("IssDatFr", "");
        writer.writeElementString("IssDatTo", "");
        writer.writeElementString("DueDatFr", formatDate10(detail.dueDateDown));
        writer.writeElementString("DueDatTo", formatDate10(detail.dueDateUp));
        writer.writeElementString("IssAmtFr", formatDecimal2(detail.billAmtDown));
        writer.writeElementString("IssAmtTo", formatDecimal2(detail.billAmtUp));
        writer.writeElementString("FrNam", "");
        writer.writeElementString("AcepNam", "");
        writer.writeElementString("ToNam", "");
        writer.writeElementString("CpsrProv", "");
        writer.writeElementString("CpsrAccNo", "");
        writer.writeElementString("CztnDatFr", "");
        writer.writeElementString("CztnDatTo", "");
        writer.writeEndElement();
        writer.writeEndElement();

        //<Cmp>
        //<DbAccNo>账号</DbAccNo>
        //<DbProv>省市代码</DbProv>
        //<DbCur>货币码</DbCur>
        //</Cmp>
        writer.writeStartElement("Cmp");
//        writer.writeElementString("DbAccNo", detail.actNum);
//        writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//        writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
        writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
        writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
        String dbCur = convertCurToBank(detail.billCur);
        writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
        writer.writeEndElement();

        //发送银行
        writer.writeEndDocument();
        String[] tmpStrRet = sendToBank(writer.toXmlString());
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                    int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                    int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                    if (tmpRecordNum > 0) {
                        String tmpDataMFS = "";
                        String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                        if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                            String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                            String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                            if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                dspClient.charsetName = getCharset();
                                TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                if (tcpRec.isCompleted) {
                                    if (tcpRec.isRtnBinaryFile) {
                                        tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                    } else {
                                        String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                        WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                    }
                                } else {
                                    this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                }
                            } else {
                                tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                            }
                            if (tmpDataMFS == null) {
                                this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                            } else {
                                this.WriteBankLogStep3(tmpDataMFS);
                            }
                        } else {
                            tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                            if (tmpDataMFS == null) {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                            }
                        }
                        if (tmpDataMFS != null) {
                            StringBuilder tmpSbLog = new StringBuilder();
                            List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                            if (tmpSbLog.length() == 0) {
                                tmpRespCode = "0";
                                        /*
                                    0票据号码|1票据金额|2票据类型|3票据类型名称|4不可转让标识|
                                    5不可转让标识名称|6出票日期|7到期日期|8出票人名称|9出票人账号|
                                    10承兑人名称|11收票人名称|12出质人（质押申请人）名称|13质权人账号|14业务编号|
										 * */
                                for (int i = 0; i < tmpArrayList.size(); i++) {
                                    RetAtsB001OperBillQryDetail respDetail = new RetAtsB001OperBillQryDetail();
                                    String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);
                                    //发生额标志(21) 0正常  1红字  2蓝字 3已抹 4抹帐


                                    respDetail.billNo = tmpEachArr[0];
                                    respDetail.billAmt = tmpEachArr[1];
                                    if ("AC01".equals(tmpEachArr[2])) {
                                        respDetail.billType = "EM001";
                                    } else if ("AC02".equals(tmpEachArr[2])) {
                                        respDetail.billType = "EM002";
                                    }
                                    if ("EM00".equals(tmpEachArr[4])) {
                                        respDetail.transFlag = "1";
                                    } else if ("EM01".equals(tmpEachArr[4])) {
                                        respDetail.transFlag = "0";
                                    }
                                    respDetail.issDate = tmpEachArr[6];
                                    respDetail.dueDate = tmpEachArr[7];
                                    respDetail.drawName = tmpEachArr[8];
                                    respDetail.drawAct = tmpEachArr[9];
                                    respDetail.accpName = tmpEachArr[10];
                                    respDetail.payeeName = tmpEachArr[11];
                                    if ("6".equals(detail.busiType)) {
                                        respDetail.applyAct = tmpEachArr[13];
                                        respDetail.receAct = tmpEachArr[12];
                                    }
                                    respDetail.busiNo = tmpEachArr[14];

                                    Resp.writeDetail(respDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "0";
                            tmpRespInfo = "数据为空";
                        }
                    }
                }
                //增加对空记录的判断
                else if ("RET002".equals(tmpBkReader.getFirstText("/ap/Hermes/Head/DealCode"))) {
                    tmpRespCode = "0";
                    tmpRespInfo = "数据为空";
                } else {
                    tmpRespCode = "-1";
                    if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {
                        tmpRespInfo = tmpRetInfo;
                    } else {
                        tmpRespInfo = tmpRetRxtInfo;
                    }
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = tmpStrRet[1];
        }


        Resp.writeRespCode(tmpRespCode);
        Resp.writeRespInfo(tmpRespInfo);

    }

    public void queryWaitingForResponse(ReqB001OperBillQryDetail detail, RetAtsB001OperBillQry Resp) throws Exception {
        ABC02Header header = new ABC02Header();
        XmlTextWriter writer = new XmlTextWriter();

        header.CCTransCode = "CQRM01";
        header.msgType = "0314";
        header.ReqDateTime = new Date();
        header.ReqSeqNo = reqHeader.transSeqID;
        writeEleCommonHead(writer, header);

        //TRE020-承兑回复
        //TRE021-收票回复
        //TRE022-背书转让回复
        //TRE029-质押回复
        //TRE030-质押解除回复
        //TRE031-保证回复
        //TRE034-同意清偿回复
        //业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-出票保证 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿
        Map<String, String> resTypMap = new HashMap<String, String>();
        resTypMap.put("2", "TRE020");
        resTypMap.put("3", "TRE021");
        resTypMap.put("4", "TRE022");
        resTypMap.put("5", "TRE029");
        resTypMap.put("6", "TRE030");
        resTypMap.put("7", "TRE031");
        resTypMap.put("8", "TRE031");
        resTypMap.put("14", "TRE034");
        if (!resTypMap.containsKey(detail.busiType)) {
            Resp.writeRespCode("-1");
            Resp.writeRespInfo("不支持的待签收业务类型【" + detail.busiType + "】");
            return;
        }

        //<IdNb>票据号码</IdNb>
        //<ResTyp>回复名称</ResTyp>
        //<BillAmtFr>票据起始金额</BillAmtFr>
        //<BilAmtTo>票据终止金额</BilAmtTo>
        //<BusDatFr>接收起始日期</BusDatFr>
        //<BusDatTo>接收终止日期</BusDatTo>
        //<AppNam>申请人名称</AppNam>
        writer.writeElementString("IdNb", detail.billNo);
        writer.writeElementString("ResTyp", resTypMap.get(detail.busiType));
        writer.writeElementString("BillAmtFr", formatDecimal2(detail.billAmtDown));
        writer.writeElementString("BilAmtTo", formatDecimal2(detail.billAmtUp));
        writer.writeElementString("BusDatFr", "");
        writer.writeElementString("BusDatTo", "");
        writer.writeElementString("AppNam", "");
        writer.writeElementString("BillTyp", ELE_BILL_TYPE.getNotNull(detail.billType));
        writer.writeEndElement();

        //<Cmp>
        //<DbAccNo>账号</DbAccNo>
        //<DbProv>省市代码</DbProv>
        //<DbCur>货币码</DbCur>
        //</Cmp>
        writer.writeStartElement("Cmp");
//        writer.writeElementString("DbAccNo", detail.actNum.length()==15?detail.actNum:detail.actNum.substring(2));
//        writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//        writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
        writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
        writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
        String dbCur = convertCurToBank(detail.billCur);
        writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
        writer.writeEndElement();

        //发送银行
        writer.writeEndDocument();
        String[] tmpStrRet = sendToBank(writer.toXmlString());
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                    int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                    int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                    if (tmpRecordNum > 0) {
                        String tmpDataMFS = "";
                        String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                        if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                            String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                            String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                            if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                dspClient.charsetName = getCharset();
                                TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                if (tcpRec.isCompleted) {
                                    if (tcpRec.isRtnBinaryFile) {
                                        tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                    } else {
                                        String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                        WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                    }
                                } else {
                                    this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                }
                            } else {
                                tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                            }
                            if (tmpDataMFS == null) {
                                this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                            } else {
                                this.WriteBankLogStep3(tmpDataMFS);
                            }
                        } else {
                            tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                            if (tmpDataMFS == null) {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                            }
                        }
                        if (tmpDataMFS != null) {
                            StringBuilder tmpSbLog = new StringBuilder();
                            List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                            if (tmpSbLog.length() == 0) {
                                tmpRespCode = "0";
                                        /*
                                    0票据号码|1回复名称|2票据金额|3接收日期|4接收时间|5申请人名称|6业务编号|7交易代码|
										 * */
                                for (int i = 0; i < tmpArrayList.size(); i++) {
                                    RetAtsB001OperBillQryDetail respDetail = new RetAtsB001OperBillQryDetail();
                                    String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);

                                    //查询明细数据
//                                    populateBillDetail(respDetail, CQRT14(detail.actNum, detail.actArea,detail.billCur,tmpEachArr[0]));

                                    switch (Integer.parseInt(detail.busiType)) {
                                        case 4: {
                                            populateCQRT11(respDetail, detail.actNum, detail.actArea, detail.billCur, tmpEachArr[0], tmpEachArr[6]);
                                            break;
                                        }
                                        case 6: {
                                            populateCQRT20(respDetail, detail.actNum, detail.actArea, detail.billCur, tmpEachArr[0], tmpEachArr[6]);
                                            break;
                                        }
                                        case 3: {
                                            populateCQRT09(respDetail, detail.actNum, detail.actArea, detail.billCur, tmpEachArr[0], tmpEachArr[6]);
                                            break;
                                        }
                                    }

                                    respDetail.billNo = tmpEachArr[0];
                                    respDetail.billAmt = tmpEachArr[2];
                                    respDetail.busiNo = tmpEachArr[6];
                                    respDetail.busiType = detail.busiType;
                                    respDetail.queryType = detail.queryType;
                                    respDetail.receAct = detail.actNum;

                                    Resp.writeDetail(respDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "0";
                            tmpRespInfo = "数据为空";
                        }
                    }
                } //增加对空记录的判断
                else if ("RET002".equals(tmpBkReader.getFirstText("/ap/Hermes/Head/DealCode"))) {
                    tmpRespCode = "0";
                    tmpRespInfo = "数据为空";
                } else {
                    tmpRespCode = "-1";
                    if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {

                        tmpRespInfo = tmpRetInfo;
                    } else {
                        tmpRespInfo = tmpRetRxtInfo;
                    }
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = tmpStrRet[1];
        }

        Resp.writeRespCode(tmpRespCode);
        Resp.writeRespInfo(tmpRespInfo);
    }

    public void queryWaitingForRevoke(ReqB001OperBillQryDetail detail, RetAtsB001OperBillQry Resp) throws Exception {
        ABC02Header header = new ABC02Header();
        XmlTextWriter writer = new XmlTextWriter();

        header.CCTransCode = "CQRM03";
        header.msgType = "0321";
        header.ReqDateTime = new Date();
        header.ReqSeqNo = reqHeader.transSeqID;
        writeEleCommonHead(writer, header);

        //可撤销出票的实际上就是撤票，这里使用撤票查询
        //农行撤票走首页查询
        if (StringHelper.equals(detail.busiType, "1")) {
            queryUnhandled(detail, Resp);
            return;
        }


//        TRE004-提示收票
//        TRE006-背书转让
//        TRE007-贴现
//        TRE012-质押
//        TRE013-解质押
//        TRE014-保证
//        TRE015-提示付款
//        TRE017-追索通知
//        TRE018-同意清偿
//业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-出票保证 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿

        //<AppTyp>申请类型</AppTyp>
        //<BillTyp>票据种类</BillTyp>
        //<IdNb>票据号码</IdNb>
        //<IssDatFr>出票起始日期</IssDatFr>
        //<IssDatTo>出票终止日期</IssDatTo>
        //<DueDatFr>起始到期日</DueDatFr>
        //<DueDatTo>终止到期日</DueDatTo>
        //<IssAmtFr>票据起始金额</IssAmtFr>
        //<IssAmtTo>票据终止金额</IssAmtTo>
        //<FrNam>出票人名称</FrNam>
        //<AcepNam>承兑人名称</AcepNam>
        //<ToNam>收票人名称</ToNam>
        if (!ELE_TRANSCODE.containsKey(detail.busiType)) {
            Resp.writeRespCode("-1");
            Resp.writeRespInfo("不支持的待撤回类业务类型【" + detail.busiType + "】");
            return;
        }
        writer.writeElementString("AppTyp", ELE_TRANSCODE.get(detail.busiType));
        writer.writeElementString("BillTyp", ELE_BILL_TYPE.getOrDefault(detail.billType, ""));
        writer.writeElementString("IdNb", detail.billNo);
        writer.writeElementString("IssDatFr", "");
        writer.writeElementString("IssDatTo", "");
        writer.writeElementString("DueDatFr", formatDate10(detail.dueDateDown));
        writer.writeElementString("DueDatTo", formatDate10(detail.dueDateUp));
        writer.writeElementString("IssAmtFr", formatDecimal2(detail.billAmtDown));
        writer.writeElementString("IssAmtTo", formatDecimal2(detail.billAmtUp));
        writer.writeElementString("FrNam", "");
        writer.writeElementString("AcepNam", "");
        writer.writeElementString("ToNam", "");
        writer.writeEndElement();

        //<Cmp>
        //<DbAccNo>账号</DbAccNo>
        //<DbProv>省市代码</DbProv>
        //<DbCur>货币码</DbCur>
        //</Cmp>
        writer.writeStartElement("Cmp");
//        writer.writeElementString("DbAccNo", detail.actNum);
//        writer.writeElementString("DbProv", getConfiguredProvince(detail.actNum));
//        writer.writeElementString("DbCur", getConfiguredCurrency(detail.actNum));
        writer.writeElementString("DbAccNo", getAbcAccNo(detail.actNum));
        writer.writeElementString("DbProv", getAbcAccProv(detail.actNum, detail.actArea));
        String dbCur = convertCurToBank(detail.billCur);
        writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
        writer.writeEndElement();

        //发送银行
        writer.writeEndDocument();
        String[] tmpStrRet = sendToBank(writer.toXmlString());
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                String tmpRetInfo = tmpBkReader.getFirstText("/ap/RespInfo");
                String tmpRetRxtInfo = tmpBkReader.getFirstText("/ap/RxtInfo");
                if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                    int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                    int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                    if (tmpRecordNum > 0) {
                        String tmpDataMFS = "";
                        String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                        if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                            String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                            String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                            if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                dspClient.charsetName = getCharset();
                                TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                if (tcpRec.isCompleted) {
                                    if (tcpRec.isRtnBinaryFile) {
                                        tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                    } else {
                                        String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                        WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                    }
                                } else {
                                    this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                }
                            } else {
                                tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                            }
                            if (tmpDataMFS == null) {
                                this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                            } else {
                                this.WriteBankLogStep3(tmpDataMFS);
                            }
                        } else {
                            tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                            if (tmpDataMFS == null) {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                            }
                        }
                        if (tmpDataMFS != null) {
                            StringBuilder tmpSbLog = new StringBuilder();
                            List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                            if (tmpSbLog.length() == 0) {
                                tmpRespCode = "0";
                                for (int i = 0; i < tmpArrayList.size(); i++) {
                                     /*
                                    0票据号码|1票据金额|2票据类型|3票据类型名称|4不可转让标识|
                                    5不可转让标识名称|6出票日期|7到期日期|8出票人名称|9出票人账号|
                                    10承兑人名称|11收票人名称|12被撤销人账号|13被撤销人名称|14被撤销人开户行行号|
                                    15被撤销人开户行名称|16撤销申请人账号|17业务编号|
										 * */
                                    RetAtsB001OperBillQryDetail respDetail = new RetAtsB001OperBillQryDetail();
                                    String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);


//                                    populateBillDetail(respDetail, CQRT14(detail.actNum, detail.actArea,detail.billCur,tmpEachArr[0]));

                                    respDetail.billNo = tmpEachArr[0];
                                    respDetail.billAmt = tmpEachArr[1];
//                                    respDetail.billType = ELE_BILL_TYPE.reverse().getOrDefault(tmpEachArr[2], tmpEachArr[3]);
//                                    respDetail.transFlag = ELE_TRANS_FLAG.reverse().getOrDefault(tmpEachArr[4], tmpEachArr[5]);
                                    if ("AC01".equals(tmpEachArr[2])) {
                                        respDetail.billType = "EM001";
                                    } else if ("AC02".equals(tmpEachArr[2])) {
                                        respDetail.billType = "EM002";
                                    }
                                    if ("EM00".equals(tmpEachArr[4])) {
                                        respDetail.transFlag = "1";
                                    } else if ("EM01".equals(tmpEachArr[4])) {
                                        respDetail.transFlag = "0";
                                    }
                                    respDetail.issDate = tmpEachArr[6];
                                    respDetail.dueDate = tmpEachArr[7];
                                    respDetail.drawName = tmpEachArr[8];
                                    respDetail.drawAct = tmpEachArr[9];
                                    respDetail.accpName = tmpEachArr[10];
                                    respDetail.payeeName = tmpEachArr[11];
                                    respDetail.applyAct = tmpEachArr[16];
                                    respDetail.receAct = tmpEachArr[12];
                                    respDetail.receName = tmpEachArr[13];
                                    respDetail.receBnkCode = tmpEachArr[14];
                                    respDetail.receBnkName = tmpEachArr[15];
                                    respDetail.busiNo = tmpEachArr[17];


                                    Resp.writeDetail(respDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "0";
                            tmpRespInfo = "数据为空";
                        }
                    }
                }//增加对空记录的判断
                else if ("RET002".equals(tmpBkReader.getFirstText("/ap/Hermes/Head/DealCode"))) {
                    tmpRespCode = "0";
                    tmpRespInfo = "数据为空";
                } else {
                    tmpRespCode = "-1";
                    if (!StringHelper.isNullOrEmpty(tmpRetInfo)) {

                        tmpRespInfo = tmpRetInfo;
                    } else {
                        tmpRespInfo = tmpRetRxtInfo;
                    }
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = tmpSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = tmpStrRet[1];
        }


        Resp.writeRespCode(tmpRespCode);
        Resp.writeRespInfo(tmpRespInfo);
    }

    /*
        public static void D_B002_BillTrans_Query_test() throws Exception {
            ABC02ElecBill trans = prepare();


            XmlTextReader reader = new XmlTextReader(
                    "<ATSYH version=\"5.1.0.0\">\n" +
                            "\t<TransReq>\n" +
                            "\t\t<BankCode>ABC</BankCode>\n" +
                            "\t\t<!--直联线路代码,参见数据字典.必填-->\n" +
                            "\t\t<TransType>B002</TransType>\n" +
                            "\t\t<!--指令类型,参见数据字典.必填-->\n" +
                            String.format("\t\t<TransSeqID>%s</TransSeqID>\n", getSeqID()) +
                            "\t\t<!--请求唯一流水号,参见数据字典.必填-->\n" +
                            String.format("\t\t<TransTime>%s</TransTime>\n", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss")) +
                            "\t\t<!--请求日期时间,参见数据字典.必填-->\n" +
                            "\t\t<TransParam>\n" +
                            "\t\t\t<ActNum>402001040005870</ActNum>\n" +
                            "\t\t\t<!--银行账号.必填-->\n" +
                            "      <BusiType>6</BusiType>\n" +
                            "      <!--业务类型 1-出票 2-承兑 3-收票 4-背书转让 5-质押 6-质押解除 7-承兑保证 8-背书保证 9-贴现 10-提示付款 11-追索 12-同意清偿-->\n" +
                            "      <QueryType>1</QueryType>\n" +
                            "      <!--查询类型 1-待操作 2-待应答 3-待撤回-->\n" +
                            "\t\t\t<BusiNo></BusiNo>\n" +
                            "\t\t\t<!--业务流水号-->\n" +
                            "\t\t\t<BillNo></BillNo>\n" +
                            "\t\t\t<!--电子票据序列号-->\n" +
                            "\t\t</TransParam>\n" +
                            "\t</TransReq>\n" +
                            "</ATSYH>"
            );

            System.out.println(trans.getSbLog());
        }
    */
    @SuppressWarnings("unused")
    public RetAtsB001OperBillQryDetail queryForAbleToRevokeBillDetail(String account, String billNo, String cancelType, String actArea, String billCur, Map<String, String> extraData) throws Exception {
        ABC02Header header = new ABC02Header();
        XmlTextWriter writer = new XmlTextWriter();

        header.CCTransCode = "CQRM03";
        header.msgType = "0321";
        header.ReqDateTime = new Date();
        header.ReqSeqNo = reqHeader.transSeqID;
        writeEleCommonHead(writer, header);

//        TRE004-提示收票
//        TRE006-背书转让
//        TRE007-贴现
//        TRE012-质押
//        TRE013-解质押
//        TRE014-保证
//        TRE015-提示付款
//        TRE017-追索通知
//        TRE018-同意清偿
//<!--撤回类型 1-承兑申请撤回 2-提示收票申请撤回 3-背书转让申请撤回 4-贴现申请撤回 5-质押申请撤回 6-（逾期）提示付款撤回 7-出票保证申请撤回 8-承兑保证申请撤回  9-背书保证申请撤回 10-追索通知撤回 11-同意清偿撤回-->
        Map<String, String> appTypMap = new HashMap<String, String>();
        appTypMap.put("2", "TRE004");
        appTypMap.put("3", "TRE006");
        appTypMap.put("4", "TRE007");
        appTypMap.put("5", "TRE012");
        appTypMap.put("7", "TRE014");
        appTypMap.put("8", "TRE014");
        appTypMap.put("9", "TRE014");
        appTypMap.put("6", "TRE015");
        appTypMap.put("10", "TRE017");
        appTypMap.put("11", "TRE018");

        //<AppTyp>申请类型</AppTyp>
        //<BillTyp>票据种类</BillTyp>
        //<IdNb>票据号码</IdNb>
        //<IssDatFr>出票起始日期</IssDatFr>
        //<IssDatTo>出票终止日期</IssDatTo>
        //<DueDatFr>起始到期日</DueDatFr>
        //<DueDatTo>终止到期日</DueDatTo>
        //<IssAmtFr>票据起始金额</IssAmtFr>
        //<IssAmtTo>票据终止金额</IssAmtTo>
        //<FrNam>出票人名称</FrNam>
        //<AcepNam>承兑人名称</AcepNam>
        //<ToNam>收票人名称</ToNam>
        if (!appTypMap.containsKey(cancelType)) {
            return null;
        }
        writer.writeElementString("AppTyp", appTypMap.get(cancelType));
        //<AppTyp>申请类型</AppTyp>
        //<BillTyp>票据种类</BillTyp>
        //<IdNb>票据号码</IdNb>
        //<IssDatFr>出票起始日期</IssDatFr>
        //<IssDatTo>出票终止日期</IssDatTo>
        //<DueDatFr>起始到期日</DueDatFr>
        //<DueDatTo>终止到期日</DueDatTo>
        //<IssAmtFr>票据起始金额</IssAmtFr>
        //<IssAmtTo>票据终止金额</IssAmtTo>
        //<FrNam>出票人名称</FrNam>
        //<AcepNam>承兑人名称</AcepNam>
        //<ToNam>收票人名称</ToNam>
        writer.writeElementString("BillTyp", "");
        writer.writeElementString("IdNb", billNo);
        writer.writeElementString("IssDatFr", "");
        writer.writeElementString("IssDatTo", "");
        writer.writeElementString("DueDatFr", "");
        writer.writeElementString("DueDatTo", "");
        writer.writeElementString("IssAmtFr", "");
        writer.writeElementString("IssAmtTo", "");
        writer.writeElementString("FrNam", "");
        writer.writeElementString("AcepNam", "");
        writer.writeElementString("ToNam", "");
        writer.writeEndElement();

        //<Cmp>
        //<DbAccNo>账号</DbAccNo>
        //<DbProv>省市代码</DbProv>
        //<DbCur>货币码</DbCur>
        //</Cmp>
        writer.writeStartElement("Cmp");
//        writer.writeElementString("DbAccNo", account);
//        writer.writeElementString("DbProv", getConfiguredProvince(account));
//        writer.writeElementString("DbCur", getConfiguredCurrency(account));
        writer.writeElementString("DbAccNo", getAbcAccNo(account));
        writer.writeElementString("DbProv", getAbcAccProv(account, actArea));
        String dbCur = convertCurToBank(billCur);
        writer.writeElementString("DbCur", StringHelper.hasAnyChar(dbCur) ? dbCur : "01");
        writer.writeEndElement();

        //发送银行
        writer.writeEndDocument();
        String[] tmpStrRet = sendToBank(writer.toXmlString());
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/RespCode");
                if (tmpRetCode != null && tmpRetCode.equals("0000")) {
                    int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/RecordNum"));
                    int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstText("/ap/Cme/FieldNum"));
                    if (tmpRecordNum > 0) {
                        String tmpDataMFS = "";
                        String tmpFileFlag = tmpBkReader.getFirstText("/ap/FileFlag");
                        if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                            String tmpBatchFileName = tmpBkReader.getFirstText("/ap/Cmp/BatchFileName");
                            String tmpFilePath = StringHelper.trimEnd(bankFront.bkQryEleFolder, File.separator) + File.separator + tmpBatchFileName;
                            this.WriteBankLogLn("读取前置数据文件：" + tmpFilePath);
                            if ("dspfileserver".equals(this.bankFront.getAccessBkFileModeLowerCase())) {
                                WriteBankLogLn("accessBkFileMode：" + bankFront.accessBkFileMode);
                                DspClient dspClient = new DspClient(bankFront.dspFileServer);
                                dspClient.charsetName = getCharset();
                                TcpReceiver tcpRec = dspClient.getFile(FileType.bankFile, tmpFilePath);
                                if (tcpRec.isCompleted) {
                                    if (tcpRec.isRtnBinaryFile) {
                                        tmpDataMFS = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                    } else {
                                        String errMsg = new String(tcpRec.recBytes, tcpRec.contentStartIndex, tcpRec.contentLength, tcpRec.charsetName);
                                        WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + errMsg);
                                    }
                                } else {
                                    this.WriteBankLogLn("从远程DSP（" + bankFront.dspFileServer + "）获取前置文件未完成：" + tcpRec.getConnMsg());
                                }
                            } else {
                                tmpDataMFS = FileHelper.readFileText(tmpFilePath, getCharset());
                            }
                            if (tmpDataMFS == null) {
                                this.WriteBankLogLn("读取前置数据文件返回完全，需确认前置文件夹配置和文件是否存在");
                            } else {
                                this.WriteBankLogStep3(tmpDataMFS);
                            }
                        } else {
                            tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData1");
                            if (tmpDataMFS == null) {
                                tmpDataMFS = tmpBkReader.getFirstText("/ap/Cmp/RespPrvData");
                            }
                        }
                        if (tmpDataMFS != null) {
                            StringBuilder tmpSbLog = new StringBuilder();
                            List<List<String>> tmpArrayList = MFSHelper.retrieveMFSData(tmpDataMFS, tmpFieldNum, tmpRecordNum);
                            if (tmpSbLog.length() == 0) {
                                for (int i = 0; i < tmpArrayList.size(); i++) {
                                     /*
                                    0票据号码|1票据金额|2票据类型|3票据类型名称|4不可转让标识|
                                    5不可转让标识名称|6出票日期|7到期日期|8出票人名称|9出票人账号|
                                    10承兑人名称|11收票人名称|12被撤销人账号|13被撤销人名称|14被撤销人开户行行号|
                                    15被撤销人开户行名称|16撤销申请人账号|17业务编号|
										 * */
                                    RetAtsB001OperBillQryDetail respDetail = new RetAtsB001OperBillQryDetail();
                                    String[] tmpEachArr = tmpArrayList.get(i).toArray(new String[0]);

                                    respDetail.billNo = tmpEachArr[0];
                                    respDetail.billAmt = tmpEachArr[1];
                                    respDetail.billType = ELE_BILL_TYPE.reverse().getOrDefault(tmpEachArr[2], tmpEachArr[3]);
                                    respDetail.transFlag = ELE_TRANS_FLAG.reverse().getOrDefault(tmpEachArr[4], tmpEachArr[5]);
                                    respDetail.issDate = tmpEachArr[6];
                                    respDetail.dueDate = tmpEachArr[7];
                                    respDetail.drawName = tmpEachArr[8];
                                    respDetail.drawAct = tmpEachArr[9];
                                    respDetail.accpName = tmpEachArr[10];
                                    respDetail.payeeName = tmpEachArr[11];
                                    respDetail.busiNo = tmpEachArr[17];

                                    extraData.put("CpdNam", tmpEachArr[13]);
                                    extraData.put("CpdOpBnk", tmpEachArr[14]);
                                    extraData.put("CpdOpBnkNam", tmpEachArr[15]);
                                    extraData.put("CrAccNo", tmpEachArr[12]);

                                    return respDetail;
                                }
                            }
                        }
                    }
                }
            }
        }

        return null;
    }
}
